/*******************************************************************************
* File Name          : W25Q128.h
* Author             : Yangjie Gu
* Description        : This file provides all the W25Q128 functions.

* History:
*  10/23/2017 : W25Q128 V1.00
*******************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __W25Q128_H_
#define __W25Q128_H_

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
//#include "stm32f1xx.h"
//#include "stm32f1xx_hal.h"
#include "all_head.h"

/* Exported constants --------------------------------------------------------*/
#define W25Q128_MANUFACTURER_ID (0xef)
#define W25Q128_DEVICE_ID (0x17)

#define W25Q128_CMD_WRITE_ENABLE (0x06)
#define W25Q128_CMD_WRITE_DISABLE (0x04)
#define W25Q128_CMD_READ_STATUS_REGISTER (0x05)
#define W25Q128_CMD_WRITE_STATUS_REGISTER (0x01)
#define W25Q128_CMD_READ_DATA (0x03)
#define W25Q128_CMD_PAGE_PROGRAM (0x02)
#define W25Q128_CMD_SECTOR_ERASE (0x20)
#define W25Q128_CMD_64K_BLOCK_ERASE (0xd8)
#define W25Q128_CMD_CHIP_ERASE (0xc7)
#define W25Q128_CMD_POWER_DOWN (0xb9)
#define W25Q128_CMD_RELEASE_POWER_DOWN (0xab)

#define W25Q128_DEFAULT_DUMMYS (0)
#define W25Q128_CMD_RELEASE_POWER_DOWN_GET_DEVICE_ID_DUMMYS (3)
#define W25Q128_SET_STATUS_REGISTER_DATA_NUM (1)
#define W25Q128_PAGE_SIZE (256)
#define W25Q128_CHIP_EARSE_TIMEOUT_FIVESECONDS (10)
#define W25Q128_SECTOR_EARSE_TIMEOUT_TENMILLISECONDS (40)
#define W25Q128_SECTOR_ADDRESS_ALIGNMENT_MASK (0xffful)
#define W25Q128_PHYSICAL_SECTOR_SIZE_BYTE (4096)
#define W25Q128_PHYSICAL_64K_BLOCK_SIZE_BYTE (1024 * 64)
#define W25Q128_SECTOR_SIZE_BYTE (2048)
#define W25Q128_BLOCK_SIZE_BYTE (2048)
#define W25Q128_CLUST_SIZE_BYTE (1024 * 64)
#define W25Q128_MEMORY_SIZE_BYTE (0x1000000ul)
#define W25Q128_RESERVE_MEMORY_SIZE_BYTE (0x200000ul)
#define W25Q128_RESERVE_MEMORY_START_ADDR (W25Q128_MEMORY_SIZE_BYTE - W25Q128_RESERVE_MEMORY_SIZE_BYTE)
#define W25Q128_FIRMWARE_INFO_START_ADDR (W25Q128_RESERVE_MEMORY_START_ADDR)
#define W25Q128_FIRMWARE_START_ADDR ((W25Q128_FIRMWARE_INFO_START_ADDR + W25Q128_PHYSICAL_SECTOR_SIZE_BYTE) & (~W25Q128_SECTOR_ADDRESS_ALIGNMENT_MASK))
#define W25Q128_FIRMWARE_MAX_SIZE (512 * 1024)
#define W25Q128_ADC_CALIBRATION_START_ADDR ((W25Q128_FIRMWARE_START_ADDR + W25Q128_FIRMWARE_MAX_SIZE) & (~W25Q128_SECTOR_ADDRESS_ALIGNMENT_MASK))
#define W25Q128_TEMPERATURE_CAL_START_ADDR (W25Q128_ADC_CALIBRATION_START_ADDR)
#define W25Q128_POWER_CAL_START_ADDR (W25Q128_TEMPERATURE_CAL_START_ADDR + W25Q128_PHYSICAL_SECTOR_SIZE_BYTE)
#define W25Q128_BATTERY_CAL_START_ADDR (W25Q128_POWER_CAL_START_ADDR + W25Q128_PHYSICAL_SECTOR_SIZE_BYTE)
#define W25Q128_MEMORY_FS_SIZE_BYTE (W25Q128_MEMORY_SIZE_BYTE - W25Q128_RESERVE_MEMORY_SIZE_BYTE)
#define W25Q128_SECTOR_COUNT (W25Q128_MEMORY_FS_SIZE_BYTE / W25Q128_SECTOR_SIZE_BYTE)
#define W25Q128_PHYSICAL_SECTOR_COUNT (W25Q128_MEMORY_FS_SIZE_BYTE / W25Q128_PHYSICAL_SECTOR_SIZE_BYTE)
#define W25Q128_PHYSICAL_64K_BLOCK_COUNT (W25Q128_MEMORY_FS_SIZE_BYTE / W25Q128_PHYSICAL_64K_BLOCK_SIZE_BYTE)

#define W25Q128_GET_FALG_MASK (0x01u)
#define W25Q128_STATUS_REG_BUSY_SHIFT (0u)
#define W25Q128_GET_FLAG(x, y) (((x) >> (y)) & W25Q128_GET_FALG_MASK)
#define W25Q128_GET_BUSY_FALG(x) W25Q128_GET_FLAG(x, W25Q128_STATUS_REG_BUSY_SHIFT)

extern SPI_HandleTypeDef hspi1;

#define W25Q128_SPI_TRANSMIT_DELAY (50)
#define W25Q128_BUSY_TIMEOUT (50)
#define W25Q128_SPI_HANDLE &hspi1

#define W25Q128_SPI_CS_PORT GPIOA
#define W25Q128_SPI_CS_PIN GPIO_PIN_15
#define W25Q128_SPI_CS_HIGH() HAL_GPIO_WritePin(W25Q128_SPI_CS_PORT, W25Q128_SPI_CS_PIN, GPIO_PIN_SET)
#define W25Q128_SPI_CS_LOW() HAL_GPIO_WritePin(W25Q128_SPI_CS_PORT, W25Q128_SPI_CS_PIN, GPIO_PIN_RESET)

/* Exported functions --------------------------------------------------------*/
extern uint8_t W25Q128_WaitBusyTimeOut(uint8_t milliseconds);

extern uint8_t W25Q128_PowerDown(void);

extern uint8_t W25Q128_RealsePowerDown_GetDeviceId(uint8_t *const pId);

extern uint8_t W25Q128_WriteEnable(void);

extern uint8_t W25Q128_ReadStatusRegister(uint8_t *const pStatusReg);

extern uint8_t W25Q128_IsBusy(void);

extern uint8_t W25Q128_SetStatusRegister(uint8_t Regvalue);

extern uint8_t W25Q128_ChipErase(void);

extern uint8_t W25Q128_ReadData(uint8_t *const pData, uint16_t num, uint32_t address);

extern uint8_t W25Q128_PageProgram(uint8_t *const pData, uint16_t num, uint32_t address);

extern uint8_t W25Q128_WriteData(uint8_t *const pData, uint16_t num, uint32_t address);

extern uint8_t W25Q128_EraseSector(uint32_t address);

extern uint8_t W25Q128_Erase64KBlock(uint32_t address);

#ifdef __cplusplus
}
#endif

#endif
